package org.seeplnframework.skyeye.common.advisor;

import com.xxl.job.core.handler.annotation.XxlJob;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import net.bytebuddy.asm.Advice;
import org.seeplnframework.skyeye.common.constants.SysConstant;
import org.seeplnframework.skyeye.common.enums.MDCConstantEnum;
import org.seeplnframework.skyeye.common.enums.RequestTypeEnum;
import org.seeplnframework.skyeye.common.util.K8sUtils;
import org.seeplnframework.skyeye.common.util.MDCUtils;
import org.seeplnframework.skyeye.common.util.SpringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

public class JobHandlerAdvisor {

    public static Logger log = LoggerFactory.getLogger(JobHandlerAdvisor.class);

    @Advice.OnMethodEnter
    public static void onMethodEnter(@Advice.This Object object,
                                     @Advice.Origin Method method,
                                     @Advice.AllArguments Object[] arguments,
                                     @Advice.Local("scope") Scope scope,
                                     @Advice.Local("span") Span span) {
        try {
            String requestParam = arguments != null && arguments.length > 0 ? (String) arguments[0] : "";
            requestParam = requestParam.length() > SysConstant.ALARM_PARAM_STR_DEFAULT ? requestParam.substring(0, SysConstant.ALARM_PARAM_STR_DEFAULT) : requestParam;
            MDCUtils.put(MDCConstantEnum.REQUEST_TYPE.getCode(), RequestTypeEnum.JOB.name().toLowerCase());
            MDCUtils.put(MDCConstantEnum.REQUEST_URI.getCode(), object.getClass().getName());
            MDCUtils.put(MDCConstantEnum.REQUEST_PARAM.getCode(), requestParam);

            //open tracing如果没有活跃可用span 弄一个放进去
            XxlJob job = method.getAnnotation(XxlJob.class);
            if (job != null) {
                //open tracing span
                Tracer tracer = SpringUtils.getBean(Tracer.class);
                if (tracer != null) {
                    Tracer.SpanBuilder spanBuilder = tracer
                            .buildSpan("xxl-job-custom-active-span")
                            .withTag(job.value(), K8sUtils.getContainerName());
                    span = spanBuilder.start();
                    scope = tracer.activateSpan(span);
                }
            }
        } catch (Exception e) {
            log.warn("log skyeye >>> JobHandlerAdvisor.onMethodEnter occur exception", e);
        }
    }

    @Advice.OnMethodExit
    public static void onMethodExit(@Advice.Local("scope") Scope scope, @Advice.Local("span") Span span) {
        //MDCUtils.clear();

        if (scope != null) {
            scope.close();
        }
        if (span != null) {
            span.finish();
        }
    }

}
